﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace CustomSerializer.Tests
{
    public class SimpleTypeArrays:IComparable
    {
        public bool[] Bool;
        public byte[] Byte;
        public sbyte[] SByte;
        public UInt16[] UInt16;
        public UInt32[] UInt32;
        public UInt64[] UInt64;
        public Int16[] Int16;
        public Int32[] Int32;
        public Int64[] Int64;
        public Single[] Single;
        public Double[] Double;
        public char[] Char;
        public Guid[] Guid;
        public DateTime[] DateTime;
        public DateTime[] DateTimeUTC;
        public DateTimeOffset[] DateTimeOffset;
        public TimeSpan[] Timespan;
        public string[] String;

        public SimpleTypeArrays() { }

        public SimpleTypeArrays(bool init)
        {
            if (!init) return;

            Random r = new Random((int) (System.DateTime.Now.Ticks%int.MaxValue));
            const int N = 100;

            Bool = Enumerable.Range(0, r.Next(N)).Select(p => r.Next(255)%2 == 0).ToArray();
            Byte = Enumerable.Range(0, r.Next(N)).Select(p => (byte)r.Next(255)).ToArray();
            SByte = Enumerable.Range(0, r.Next(N)).Select(p => (sbyte) (r.Next(127) - 250)).ToArray();

            UInt16 = Enumerable.Range(0, r.Next(N)).Select(p => (UInt16) r.Next(System.UInt16.MaxValue)).ToArray();
            Int16 = Enumerable.Range(0, r.Next(N)).Select(p => (Int16)(r.Next(System.UInt16.MaxValue) - System.UInt16.MaxValue/2)).ToArray();

            UInt32 = Enumerable.Range(0, r.Next(N)).Select(p => (UInt32)r.Next(System.Int32.MaxValue)).ToArray();
            Int32 = Enumerable.Range(0, r.Next(N)).Select(p => r.Next(System.Int32.MaxValue) - System.Int32.MaxValue / 2).ToArray();

            UInt64 = Enumerable.Range(0, r.Next(N)).Select(p => (UInt64) r.Next(System.Int32.MaxValue)).ToArray();
            Int64 = Enumerable.Range(0, r.Next(N)).Select(p => (Int64) (r.Next(System.Int32.MaxValue) - System.Int32.MaxValue/2)).ToArray();

            Single = Enumerable.Range(0, r.Next(N)).Select(p => (Single)(r.Next(System.Int32.MaxValue)/100.0)).ToArray();
            Double = Enumerable.Range(0, r.Next(N)).Select(p => (Double) (r.Next(System.Int32.MaxValue)/100.0)).ToArray();
            Char = new[] {'W', 'Ы', 'Ѽ'};

            Guid = new[]
            {
                new Guid(Enumerable.Range(0, 16).Select(p => (byte)((r.Next(255) * p) & 0xFF)).ToArray()),
                new Guid(Enumerable.Range(0, 16).Select(p => (byte)((r.Next(255) * p) & 0xFF)).ToArray())
            };

            DateTime = new[]
            {
                new DateTime(2015, 1, 1, 1, 1, 1, DateTimeKind.Local).AddDays(r.Next(31)),
                new DateTime(2015, 1, 1, 1, 1, 1, DateTimeKind.Local).AddDays(r.Next(31)),
                new DateTime(2015, 1, 1, 1, 1, 1, DateTimeKind.Local).AddDays(r.Next(31)),
            };

            DateTimeUTC = new[]
            {
                new DateTime(2014, 1, 1, 1, 1, 1, DateTimeKind.Utc).AddDays(r.Next(31)),
                new DateTime(2014, 1, 1, 1, 1, 1, DateTimeKind.Utc).AddDays(r.Next(31)),
                new DateTime(2014, 1, 1, 1, 1, 1, DateTimeKind.Utc).AddDays(r.Next(31))
            };

            DateTimeOffset = DateTimeUTC.Select(p => new DateTimeOffset(new DateTime(p.Ticks, DateTimeKind.Unspecified), TimeSpan.FromHours(r.Next(12) - 6))).ToArray();
        }

        int IComparable.CompareTo(object obj)
        {
            return 0;
        }
    }

    public class SimpleTypesNullableArrays:IComparable
    {
        public bool?[] Bool;
        public byte?[] Byte;
        public sbyte?[] SByte;
        public UInt16?[] UInt16;
        public UInt32?[] UInt32;
        public UInt64?[] UInt64;
        public Int16?[] Int16;
        public Int32?[] Int32;
        public Int64?[] Int64;
        public Single?[] Single;
        public Double?[] Double;
        public char?[] Char;
        public Guid?[] Guid;
        public DateTime?[] DateTime;
        public DateTime?[] DateTimeUTC;
        public DateTimeOffset?[] DateTimeOffset;
        public TimeSpan?[] Timespan;

        public SimpleTypesNullableArrays() { }

        public SimpleTypesNullableArrays(bool init)
        {
            Random r = new Random((int)(System.DateTime.Now.Ticks % int.MaxValue));
            const int N = 100;

            Bool = Enumerable.Range(0, r.Next(N)).Select(p => new bool?(r.Next(255) % 2 == 0)).ToArray();
            Byte = Enumerable.Range(0, r.Next(N)).Select(p => (byte?)r.Next(255)).ToArray();
            SByte = Enumerable.Range(0, r.Next(N)).Select(p => (sbyte?)(r.Next(127) - 250)).ToArray();

            UInt16 = Enumerable.Range(0, r.Next(N)).Select(p => (UInt16?)r.Next(System.UInt16.MaxValue)).ToArray();
            Int16 = Enumerable.Range(0, r.Next(N)).Select(p => (Int16?)(r.Next(System.UInt16.MaxValue) - System.UInt16.MaxValue / 2)).ToArray();

            UInt32 = Enumerable.Range(0, r.Next(N)).Select(p => (UInt32?)r.Next(System.Int32.MaxValue)).ToArray();
            Int32 = Enumerable.Range(0, r.Next(N)).Select(p => (int?) (r.Next(System.Int32.MaxValue) - System.Int32.MaxValue/2)).ToArray();

            UInt64 = Enumerable.Range(0, r.Next(N)).Select(p => (UInt64?)r.Next(System.Int32.MaxValue)).ToArray();
            Int64 = Enumerable.Range(0, r.Next(N)).Select(p => (Int64?)(r.Next(System.Int32.MaxValue) - System.Int32.MaxValue / 2)).ToArray();

            Single = Enumerable.Range(0, r.Next(N)).Select(p => (Single?)(r.Next(System.Int32.MaxValue) / 100.0)).ToArray();
            Double = Enumerable.Range(0, r.Next(N)).Select(p => (Double?)(r.Next(System.Int32.MaxValue) / 100.0)).ToArray();
            Char = new char?[] { 'W', 'Ы', 'Ѽ' };

            Guid = new Guid?[]
            {
                new Guid(Enumerable.Range(0, 16).Select(p => (byte)((r.Next(255) * p) & 0xFF)).ToArray()),
                new Guid(Enumerable.Range(0, 16).Select(p => (byte)((r.Next(255) * p) & 0xFF)).ToArray())
            };

            DateTime = new DateTime?[]
            {
                new DateTime(2015, 1, 1, 1, 1, 1, DateTimeKind.Local).AddDays(r.Next(31)),
                new DateTime(2015, 1, 1, 1, 1, 1, DateTimeKind.Local).AddDays(r.Next(31)),
                new DateTime(2015, 1, 1, 1, 1, 1, DateTimeKind.Local).AddDays(r.Next(31)),
            };

            DateTimeUTC = new DateTime?[]
            {
                new DateTime(2014, 1, 1, 1, 1, 1, DateTimeKind.Utc).AddDays(r.Next(31)),
                new DateTime(2014, 1, 1, 1, 1, 1, DateTimeKind.Utc).AddDays(r.Next(31)),
                new DateTime(2014, 1, 1, 1, 1, 1, DateTimeKind.Utc).AddDays(r.Next(31))
            };

            DateTimeOffset = DateTimeUTC.Select(p => (DateTimeOffset?) new DateTimeOffset(new DateTime(p.Value.Ticks, DateTimeKind.Unspecified), TimeSpan.FromHours(r.Next(12) - 6))).ToArray();
        }

        int IComparable.CompareTo(object obj)
        {
            return 0; // todo
        }
    }    
}